﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SharpKit.JavaScript;

namespace SharpKit.Onx
{
    /// <summary>
    /// Http allows sending http requests
    /// https://www.onx.ms/#apiPage/httpClient
    /// </summary>
    [JsType(Mode = JsMode.Prototype, Export = false)]
    public class httpClient
    {
        //No way to new this up
        private httpClient()
        { }

        #region Actions (Methods)
        /// <summary>
        /// Sends an http request This method should be invoked from JavaScript.
        /// </summary>
        /// <param name="args">the ajax object</param>
        /// <param name="onSuccess">A callback to be called when the http response is returned with no error. Default is null.</param>
        /// <param name="onError">A callback to be called when the http fails with an error. Default is null.</param>
        /// <returns>the request object, it can be used to cancel pending ajax operation.</returns>
        [JsMethod(Name = "ajax")]
        public HttpScriptClientPromise Ajax(AjaxArguments args, AjaxSuccessCallback onSuccess = null, AjaxErrorCallback onError = null)
        { return null; }
        #endregion
    }

    /// <summary>
    /// A callback to be called when the http response is returned with no error. Default is null.
    /// Data holds the body of the response. Text status is the response status line.
    /// </summary>
    /// <param name="body">the body of the response</param>
    /// <param name="textStatus">the response status line</param>
    /// <param name="response">a AjaxResponse object</param>
    public delegate void AjaxSuccessCallback(string body, string textStatus, AjaxResponse response);

    /// <summary>
    /// A callback to be called when the http fails with an error. Default is null.
    /// Text status is the response status line, or a descriptive error message in case response was null.
    /// (you can't have both an error and a response callback called from the request).
    /// </summary>
    /// <param name="textStatus">the response status line, or a descriptive error message in case response was null</param>
    /// <param name="response">a AjaxResponse object</param>
    public delegate void AjaxErrorCallback(string textStatus, AjaxResponse response);

    /// <summary>
    /// The response object supports the following properties: 
    ///     String statusText - The response status summary. 
    ///     int status - The response status code. 
    ///     Dictionary headers - A JavaScript dictionary of the response headers.
    /// </summary>
    [JsType(Mode = JsMode.Prototype, Export = false)]
    public class AjaxResponse
    {
        /// <summary>
        /// Can't new this up
        /// </summary>
        private AjaxResponse()
        {
        }

        /// <summary>
        /// The response status summary
        /// </summary>
        [JsProperty(Name = "statusText", NativeField = true)]
        public string StatusText { get { return null; } }

        /// <summary>
        /// The response status code. 
        /// </summary>
        [JsProperty(Name = "status", NativeField = true)]
        public int Status { get { return 0; } }

        /// <summary>
        /// A JavaScript dictionary of the response headers.
        /// </summary>
        [JsProperty(Name = "headers", NativeField = true)]
        public JsObject<string, string> Headers { get { return null; } }
    }

    /// <summary>
    /// the ajax object
    /// </summary>
    [JsType(Mode = JsMode.Prototype, Export = false)]
    public class AjaxArguments
    {
        /// <summary>
        /// REQUIRED. A string containing the URL to which the request is sent.
        /// </summary>
        [JsProperty(Name = "url", NativeField = true)]
        public string Url { get; set; }

        /// <summary>
        /// The type of request to make ('POST' or 'GET'). Default is GET.
        /// </summary>
        [JsProperty(Name = "type", NativeField = true)]
        public AjaxType Type { get; set; }

        /// <summary>
        /// Data to be sent to the server. Default is null.
        /// </summary>
        [JsProperty(Name = "data", NativeField = true)]
        public string Data { get; set; }

        /// <summary>
        /// A map of additional header key/value pairs to send along with the request (default is null).
        /// </summary>
        [JsProperty(Name = "headers", NativeField = true)]
        public object Headers { get; set; }
    }

    /// <summary>
    /// 
    /// </summary>
    [JsType(JsMode.Json, Export = false)]
    [JsEnum(ValuesAsNames = true)]
    public enum AjaxType
    {
        /// <summary>
        /// 
        /// </summary>
        [JsField(Name = "GET")]
        Get,

        /// <summary>
        /// 
        /// </summary>
        [JsField(Name = "POST")]
        Post
    }

    /// <summary>
    /// This class can be used to cancel a pending ajax operation.
    /// </summary>
    [JsType(Mode = JsMode.Prototype, Export = false)]
    public class HttpScriptClientPromise
    {
        //No way to new this up
        private HttpScriptClientPromise()
        { }

        /// <summary>
        /// Aborts the pending ajax request.
        /// </summary>
        [JsMethod(Name = "abort")]
        public void Abort() { }
    }
}